package jumpingnotes.dao.hibernate;

import java.util.List;

import jumpingnotes.dao.MemberDao;
import jumpingnotes.model.entity.Member;
import net.jf.lucene.analysis.mmseg.MMSegAnalyzer;

import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.springframework.orm.hibernate3.HibernateCallback;

public class MemberHibernateDao extends GenericHibernateDao<Member> implements MemberDao
{
	public MemberHibernateDao()
	{
		super(Member.class);
	}

	@SuppressWarnings("unchecked")
	public List<Member> findMemberByGroupId(final int groupId, final int firstResult, final int maxResults)
	{
		return (List<Member>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Query query = session
						.createQuery("select distinct m from Member m join m.groupMembers gm where gm.group.groupId=:groupId order by gm.createTime desc");
				query.setInteger("groupId", groupId);

				if (firstResult >= 0)
					query.setFirstResult(firstResult);
				if (maxResults > 0)
					query.setMaxResults(maxResults);

				return query.list();
			}
		});
	}

	public Member findMemberByEmail(final String email)
	{
		return (Member) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Query query = session.createQuery("select distinct m from Member m where m.email=:email");
				query.setString("email", email);
				return query.uniqueResult();
			}
		});
	}

	@SuppressWarnings("unchecked")
	public List<Member> findMemberByFriendMemberId(final int memberId, final int firstResult, final int maxResults)
	{
		return (List<Member>) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
//				SQLQuery query = session
//						.createSQLQuery("select m.* from member m join friend f where m.member_id=f.member_id_to and f.member_id_from=:memberIdFrom union select m.* from member m join friend f where m.member_id=f.member_id_from and f.member_id_to=:memberIdTo");
//				query.addEntity(Member.class);
//				query.setInteger("memberIdFrom", memberId);
//				query.setInteger("memberIdTo", memberId);

				Query query = session.createQuery("select distinct f.memberByMemberIdTo from Friend f where f.memberByMemberIdFrom.memberId=:memberId");
				query.setInteger("memberId", memberId);
				
				if (firstResult >= 0)
					query.setFirstResult(firstResult);
				if (maxResults > 0)
					query.setMaxResults(maxResults);

				return query.list();
			}
		});
	}

	public int countMemberByFavoriteBook(final int bookId)
	{
		return ((Long) getHibernateTemplate().execute(new HibernateCallback()
		{
			public Object doInHibernate(Session session) throws HibernateException
			{
				Query query = session
						.createQuery("select count(*) from Member m join m.bookFavorites bf where bf.book.bookId=:bookId");
				query.setInteger("bookId", bookId);
				return query.uniqueResult();
			}
		})).intValue();
	}

	@SuppressWarnings("unchecked")
	public void indexMember()
	{
		Session session = getSession();
		FullTextSession fullTextSession = Search.createFullTextSession(session);

		List<Member> memberList = session.createCriteria(Member.class).list();
		for (Member member : memberList)
		{
			fullTextSession.index(member);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Member> searchMember(String keyword, int firstResult, int maxResults)
	{
		Session session = getSession();
		FullTextSession fullTextSession = Search.createFullTextSession(session);

		try
		{
			MultiFieldQueryParser parser = new MultiFieldQueryParser(new String[] {
					"nickName", "aboutMe", "locationCity", "locationProvince", "locationCountry"
			}, new MMSegAnalyzer());
			org.apache.lucene.search.Query query = parser.parse(keyword);
			Query hibQuery = fullTextSession.createFullTextQuery(query, Member.class);

			if (firstResult >= 0)
				hibQuery.setFirstResult(firstResult);
			if (maxResults > 0)
				hibQuery.setMaxResults(maxResults);

			List<Member> result = hibQuery.list();
			return result;
		}
		catch (ParseException e)
		{
			e.printStackTrace();
			return null;
		}
	}
}
